import os, sys, time, asyncio, aiohttp

import re

import pymysql
import tqdm

# FLAGS = ('277982 277983 277984 277985 277986 277987').split()
BASE_URL = 'https://www.apk3.com/soft'  # 下载url
DEST_DIR = 'downloads/'  # 保存目录
headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.13 Safari/537.36',
    "Referer": "http://www.v2ex.com/signin"
}


# 获取链接,下载文件
async def fetch(session: aiohttp.ClientSession, url: str, path: str, flag: str):
    # flag = {str} 'IN'
    # path = {str} 'downloads/in.gif'
    # url = {str} 'http://flupy.org/data/flags/in/in.gif'
    # print(flag, ' 开始下载')
    async with session.get(url, headers=headers, timeout=5000) as resp:
        try:
            html = await resp.read()
            html = html.decode('gb2312', 'ignore')
            typelocation = re.search(r'安卓软件下载网</a> → <a href="/game/">安卓游戏</a>', html)
            if typelocation != None:
                apkUrlList = re.findall('href="(http.*?\.apk)"', html)
                apkSizeList = re.findall('(\d+\.?\d?)MB', html)
                appName = re.findall('<div class="a_app_attr_tit">\n<h1>(.*?)</h1>', html)
                # path = "E:/app/apk/%s.apk" % (appName[0] if appName.__len__() > 0 else str(0))
                if apkUrlList.__len__() > 0:
                    if apkSizeList.__len__() > 0:
                        if (float(apkSizeList[0])) < 100.0:
                            print('\n正在下载>>>>', apkUrlList[0])
                            installNO(cursor, db, flag, (appName[0] if appName.__len__() > 0 else str(0)),
                                      apkUrlList[0])
                            # installNO(cursor, db, flag, ">>>>", "<<<<;")
                        #else:
                            # print("\n超过指定大小%s" % flag)
                   # else:
                      #  print("\n未找到大小信息%s" % flag)
              #  else:
                    #print("\n未找到下载地址%s" % flag)
           # else:
              #  print("\n不是游戏%s" % flag)
        except Exception as e:
            aiohttp.traceback.print_exc()
            print("boom!!!%s" % url)
    return flag


async def begin_download(sem, session: aiohttp.ClientSession, url: str, path: str, flag: str):
    # 控制协程并发数量
    with (await sem):
        return await fetch(session, url, path, flag)


async def download(sem: asyncio.Semaphore):
    tasks = []
    async with aiohttp.ClientSession() as session:
        for flag in FLAGS:
            # 创建路径以及url
            path = os.path.join(DEST_DIR, '%s.html' % flag)
            url = '{}/{cc}.html'.format(BASE_URL, cc=flag)
            # 构造一个协程列表
            tasks.append(asyncio.ensure_future(begin_download(sem, session, url, path, flag)))
        # 等待返回结果
        tasks_iter = asyncio.as_completed(tasks)
        # 创建一个进度条
        fk_task_iter = tqdm.tqdm(tasks_iter, total=len(FLAGS))
        for coroutine in fk_task_iter:
            res = await coroutine
            # print(res, '下载完成')


# 查询上次最后一次的序号
def selectNo(cursor):
    cursor.execute("select *  from apk3 where _id=(select max(_id)  from apk3)")
    maxNO = cursor.fetchall()
    if maxNO.__len__() > 0:
        firstNo = maxNO[0][1]
        return int(firstNo) + 1
    return 0


# 插入序号
def installNO(cursor, db, NO, appName="", downAddress=""):
    # 'insert into apk3(NO,appName,downAddress) values (277982,星王高爆版下载 5.0,https://dlres.63yx.com/h5zy/10111-721343/xwgbb.apk)'
    sql = "insert into apk3(No,appName,downAddress) values (%d,'%s','%s')" % (NO, appName, downAddress)
    cursor.execute(sql)
    db.commit()
    db.rollback()

if __name__ == '__main__':
    db = pymysql.connect("localhost", "root", "164531", "appmsg")
    cursor = db.cursor()

    firstNo = selectNo(cursor)
    # firstNo = 277982
    FLAGS = []
    # 15000~20000
    # firstNo=20000
    for i in range(45000, 50000):
        FLAGS.append(i)

    # 创建目录
    os.makedirs(DEST_DIR, exist_ok=True)
    # 获取事件循环
    lp = asyncio.get_event_loop()
    start = time.time()
    # 创建一个信号量以防止DDos
    sem = asyncio.Semaphore(4)
    lp.run_until_complete(download(sem))
    end = time.time()
    lp.close()
    print('耗时:', end - start)
